<?php 
use	Workerman\Worker; 
require_once	'./Workerman/Autoloader.php';
require_once	'./mysql/src/Connection.php';

//	初始化一个worker容器，监听1234端口
$worker	=	new	Worker('tcp://0.0.0.0:2000');
/*
 *	注意这里进程数必须设置为1，否则会报端口占用错误
 *	(php	7可以设置进程数大于1，前提是$inner_text_worker->reusePort=true)
 */
$worker->count = 1;

$worker->onConnect = function($connection){
	log_record('【'.date("Y-m-d H:i:s").' ip：'.$connection->getRemoteIp().'】：'.'进行连接'."\r\n");
};

//新增加一个属性，用来保存uid到connection的映射 
$worker->uidConnections	= array();
//新增加一个属性，用来保存php到connection的映射 
//$worker->phpConnections	= array();
//	worker进程启动后创建一个text	Worker以便打开一个内部通讯端口
$worker->onWorkerStart	= function($worker){
	//	将db实例存储在全局变量中(也可以存储在某类的静态成员中)
	global $db;
	global $worker;
	$db  = new \Workerman\MySQL\Connection('112.74.84.200','3306','root','Tosky2016', 'dream_flower'); 
	//	开启一个内部端口，方便内部系统推送数据，Text协议格式	文本+换行符
	$inner_text_worker	= new Worker('text://0.0.0.0:2001');
	//该端口有数据发来时，触发函数
	$inner_text_worker->onMessage = function($connection,$buffer){
		global $worker;
		//	$data转化成数组格式，里面有uid，表示向那个uid的页面推送数据
		$data = decodeJson($buffer,true);
		$uid = $data['uid'];
		$value = $data['value'];
		if(isset($worker->uidConnections[$uid])){
			//通过workerman，向uid的页面推送数据
			$ret = sendMessageByUid($uid,$value."\n");
			//返回推送结果
			//$connection->send($ret?'ok':'fail');
			//保存PHP端的连接信息
			$_SESSION['connection'][$uid] = $connection;
		}else{
			$connection->send('2');
			log_record('【'.date("Y-m-d H:i:s").' ip：'.$connection->getRemoteIp().'】：'.'uid为'.$uid.'的硬件设备没连接'."\r\n");
		}
	};
	//	##	执行监听	##
	$inner_text_worker->listen();
};
//当有客户端发来消息时执行的回调函数 
$worker->onMessage = function($connection,$data){
	global $worker;
	global $db;
	$image = substr($data,0,6);
	if($image == 'image')
		$real_image = $image;
	unset($image);
	if(!isset($real_image)){
		$datas = trim($data);
		$datas = decodeJson($datas);
	}
	//	判断当前客户端是否已经验证,既是否设置了uid
	// var_dump($data);
	if((!isset($connection->uid) || isset($datas['uid'])) && !isset($real_image)){
		if(!is2string($datas['uid'])){
			log_record('【'.date("Y-m-d H:i:s").' ip：'.$connection->getRemoteIp().'】：'.'uid输入不规范'."\r\n");
			return;
		}else{
			$insert['uid'] = $insert2['uid'] = $insert3['uid'] = $datas['uid'];//识别id
			$insert['ip'] = $insert2['ip'] = $insert3['ip'] = $connection->getRemoteIp();//客户端ip
			$result = $db->select('ip')->from('dream_connect_info')->where("uid = '".$insert3['uid']."'")->row();
			// var_dump($insert);
			if($result){
				//是否重新连接
				if($result['ip'] != $connection->getRemoteIp()){
					log_record('【'.date("Y-m-d H:i:s").' ip：'.$connection->getRemoteIp().'】：'.'uid('.$datas['uid'].')有误'."\r\n");
					return;
					// $connection->send('uid or ip error '."\n");//错误处理成日记
				}else{
					$connection->uid = $datas['uid'];
					$worker->uidConnections[$connection->uid] = $connection;
					$ret = sendMessageByUid($connection->uid,'{11}'."\n");//回复硬件连接成功
					//返回推送结果
					$ret?(log_record('【'.date("Y-m-d H:i:s").' ip：'.$connection->getRemoteIp().'】：硬件设备uid为'.$datas['uid'].'，重新连接成功，并发送{11}给硬件'."\r\n")):(log_record('【'.date("Y-m-d H:i:s").' ip：'.$connection->getRemoteIp().'】：硬件设备uid为'.$datas['uid'].'重新连接成功，发送{11}给硬件失败'."\r\n"));//处理成日记
					return;
				}
			}else{
				// $result = $db->select('uid')->from('dream_datas')->where("ip = '".$insert2['ip']."'")->row();
				// $ok2 = true;
				// if(!$result){
					$insert2['switch'] = '00';
					$ok2 = $db->insert('dream_datas')->cols($insert2)->query();
				// }else{
					// $result2 = $db->select('uid')->from('dream_datas')->where("uid = '".$insert2['uid']."'")->row();
				// 	if(!$result2){
				// 		$connection->send('uid chu ru cuowu'."\n");
				// 		return;
				// 	}
				// }
				$ok1 = $db->insert('dream_connect_info')->cols($insert)->query();
				if($ok1 && $ok2){
					//保存uid标识
					$connection->uid = $datas['uid'];
					/*	保存uid到connection的映射，这样可以方便的通过uid查找connection
					*	实现针对特定uid推送数据
					*/
					$worker->uidConnections[$connection->uid] = $connection;
					$ret = sendMessageByUid($connection->uid,'{11}'."\n");
					//返回推送结果
					$ret?(log_record('【'.date("Y-m-d H:i:s").' ip：'.$connection->getRemoteIp().'】：硬件设备uid为'.$datas['uid'].'，第一次连接成功，并发送{11}给硬件'."\r\n")):(log_record('【'.date("Y-m-d H:i:s").' ip：'.$connection->getRemoteIp().'】：硬件设备uid为'.$datas['uid'].'，第一次连接成功，并发送{11}给硬件'."\r\n"));
				}else log_record('【'.date("Y-m-d H:i:s").' ip：'.$connection->getRemoteIp().'】：'.'第一次连接时mysql出错，硬件设备uid为'.$datas['uid']."\r\n");
				
			}
		}
	}else{
		
		var_dump($datas);
		//echo $result['light_intensity'];
		//echo $connection->uid;
		//var_dump($data);
		// sendMessageByUid($connection->uid,'你发送了'.$data."\n");
		if(isset($datas['status']) && !isset($real_image)){
			sendMessageToPhp($connection->uid,$datas['status']."\n");
			// sendMessageByUid($connection->uid,'你发送了'.$data."\n");
		}

			//接送图片
		if($real_image == 'image'){
			$image_byte = substr($data,6);
			$icon_hex = bin2hex($image_byte);
			// $search = array(" ","　","\n","\r","\t");
			// $replace = array("","","","","");
			// $icon_hex = str_replace($search, $replace, $icon_hex);
	    	$imgdata = pack('H*',$icon_hex);
	    	$savePath = './Public/share/images/uploads/'; // 设置附件上传（子）目录
	    	if(!file_exists($savePath))
	    		//检查是否有该文件夹，如果没有就创建，并给予最高权限
				mkdir($savePath, 0700);
			$image_name = time().'.jpg';
			$new_file = $savePath.$image_name;
			// $new_file = $savePath.time();
			// var_dump($_GET);
			// $data = $_GET;
			if (file_put_contents($new_file, $imgdata)){
				$value['image'] = '/share/images/uploads/'.$image_name;
				$ok	= $db->update('dream_datas')->cols($value)->where("uid = '".$connection->uid."'")->query();
				if($ok)
					echo '新文件保存成功：', $new_file;
			}else{
				echo '新文件保存失败';
			}
		}
	}
	return;
};
//	当有客户端连接断开时
$worker->onClose = function($connection){
	global $worker;
	global $db;
	if(isset($connection->uid)){
		//删除客户端的连接数据
		//$result = $db->delete('workerman')->where("uid = $connection->uid")->query();
		//if($result>0) echo "删除成功！"."\n";
		echo $connection->uid.'close'."\n";
		//	连接断开时删除映射
		unset($worker->uidConnections[$connection->uid]);
		if(isset($_SESSION['connection'][$connection->uid]))
			unset($_SESSION['connection'][$connection->uid]);
	}
};


//	向所有验证的用户推送数据 
function broadcast($message){
	global	$worker;
	foreach($worker->uidConnections	as	$connection){
		$connection->send($message);
	}
}

//	针对uid推送数据
function sendMessageByUid($uid,	$message){
	global	$worker;
	if(isset($worker->uidConnections["$uid"])){
		$connection	= $worker->uidConnections["$uid"];
		$connection->send($message);
		return	true;
	}
	return	false;
}

//	针对uid推送数据
function sendMessageToPhp($uid,	$message){
	global	$worker;
	if(isset($_SESSION['connection']["$uid"])){
		$connection	= $_SESSION['connection']["$uid"];
		$connection->send($message);
		return	true;
	}
	return	false;
}

/**
 * 判断参数是否为字符串
 * @param mixed $str 要判断的变量
 * @param string $filter 条件,多个逗号分隔,如"c,e,n"(如-> n:数字, c:中文, e:英文)
 * @param string $other 其它字符 (如:_*%)
 */
function is2string($str='',$filter='',$other=''){
    if($str=='')
        return false;
    if(!is_numeric($str) AND !is_string($str))
        return false;
    //正由规则变量
    $match = '';
    //filter 条件
    if($filter!=''){
        $filter = My::explode(',',$filter);
        if(is_array($filter)){
            //英文字母
            if(in_array('e',$filter))
                $match .= 'a-zA-Z';
            //数字
            if(in_array('n',$filter))
                $match .= '0-9';
            //中文
            if(in_array('c',$filter))
                $match .= '\x{4e00}-\x{9fa5}';
        }
    }
    //其它正则特殊字符
    if($other!='')
        $match .= $other;
    //验证正则规则
    if($match!='' AND !preg_match('/^['.$match.']+$/u', $str))
        return false;
    return true;
};

 /**
 * json_decode ：json解码
 * @param string $str 等解码字符串
 * @return array
 */
function decodeJson($str=''){
    if(!$str OR !is_string($str)) return $str;
    return json_decode($str,true);
}

/**
 * log ：存储日记
 * @param string $str 等解码字符串
 * @return array
 */
function log_record($content){
	$folder = date("Y-m-d",time());//文件夹名
	$file = date("Y-m-d H",time()).'.txt';//文件夹名
	$path = './Data/Log/Service/';
	$folder_path = $path.$folder;
	$dir = iconv("UTF-8", "GBK", $folder_path);
	if (!file_exists($dir))
        mkdir ($dir,0777,true);
    $file_path = $folder_path.'/'.$file;
    error_log($content,3,$file_path);
    return true;
}
//	运行所有的worker Worker::runAll();
Worker::runAll();
